/*
 * Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.wso2.carbon.registry.extensions.handlers.utils;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.registry.core.Association;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.RegistryConstants;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.ResourceImpl;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.jdbc.handlers.RequestContext;
import org.wso2.carbon.registry.core.session.CurrentSession;
import org.wso2.carbon.registry.core.utils.RegistryUtils;
import org.wso2.carbon.registry.extensions.services.Utils;
import org.wso2.carbon.registry.extensions.utils.CommonConstants;
import org.wso2.carbon.registry.extensions.utils.CommonUtil;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class EndpointUtils {
    private static final Log log = LogFactory.getLog(EndpointUtils.class);

    private static final String SOAP11_ENDPOINT_EXPR = "/wsdl:definitions/wsdl:service/wsdl:port/soap:address";
    private static final String SOAP12_ENDPOINT_EXPR = "/wsdl:definitions/wsdl:service/wsdl:port/soap12:address";
    private static final String HTTP_ENDPOINT_EXPR = "/wsdl:definitions/wsdl:service/wsdl:port/http:address";
    private static final String SERVICE_ENDPOINT_ENTRY_EXPR = "/s:metadata/s:endpoints/s:entry";
    private static final String SERVICE_ENDPOINT_EXPR = "/s:metadata/s:endpoints";
    private static final String SERVICE_ENDPOINTS_ELEMENT = "endpoints";
    private static final String SERVICE_ENDPOINTS_ENTRY_ELEMENT = "entry";
    private static final String LOCATION_ATTR = "location";

    private static final String SYNAPSE_ENDPOINT = "endpoint";
    private static final String SYNAPSE_ENDPOINT_NAME_ATTRIBUTE = "name";
    private static final String SYNAPSE_ENDPOINT_ADDRESS = "address";
    private static final String SYNAPSE_ENDPOINT_ADDRESS_URI_ATTRIBUTE = "uri";
    private static final String SYNAPSE_ENDPOINT_OVERVIEW = "overview";
    private static final String SYNAPSE_ENDPOINT_VERSION = "version";
    private static final String SYNAPSE_ENDPOINT_NAME = "name";
    private static final String ENDPOINT_RESOURCE_PREFIX = "ep-";
    private static final String ENDPOINT_NAMESPACE_ATTRIBUTE = "xmlns";
    private static final String ENDPOINT_ELEMENT_NAMESPACE = "http://www.wso2.org/governance/metadata";
    private static String endpointVersion = CommonConstants.ENDPOINT_VERSION_DEFAULT_VALUE;

    private static final String ENDPOINT_DEFAULT_LOCATION = "/trunk/endpoints/";
    private static String endpointLocation = ENDPOINT_DEFAULT_LOCATION;
    private static String endpointMediaType = CommonConstants.ENDPOINT_MEDIA_TYPE;

    private static boolean includeNamespaceInName = false;

    public static boolean isIncludeNamespaceInName() {
        return includeNamespaceInName;
    }

    public static void setIncludeNamespaceInName(boolean includeNamespaceInName) {
        EndpointUtils.includeNamespaceInName = includeNamespaceInName;
    }

    public static void setEndpointLocation(String endpointLocation) {
        EndpointUtils.endpointLocation = endpointLocation;
    }

    public static String getEndpointLocation() {
        return endpointLocation;
    }

    public static void setEndpointMediaType(String mediaType) {
        endpointMediaType = mediaType;
    }

    public static String getEndpointMediaType() {
        return endpointMediaType;
    }

    public static void removeEndpointEntry(String oldWSDL, String servicePath, OMElement serviceElement, Registry registry)
            throws RegistryException {
        List<OMElement> serviceEndpointEntryElements = getOmElements(serviceElement);
        if (serviceEndpointEntryElements == null || serviceEndpointEntryElements.size() == 0) {
            return;
        }
        String endpointURL = null;
        if (registry.resourceExists(oldWSDL)){
            Association[] associations = registry.getAssociations(oldWSDL, CommonConstants.DEPENDS);
            for (Association association: associations) {
                String targetPath = association.getDestinationPath();
                if (registry.resourceExists(targetPath)) {
                    Resource targetResource = registry.get(targetPath);
                    if (CommonConstants.ENDPOINT_MEDIA_TYPE.equals(targetResource.getMediaType())) {
                        byte[] sourceContent = (byte[]) targetResource.getContent();
                        if (sourceContent == null) {
                            continue;
                        }
                        endpointURL = EndpointUtils.deriveEndpointFromContent(RegistryUtils.decodeBytes(sourceContent));
                    }
                }
            }
        }

       for(OMElement endpointOmElement : serviceEndpointEntryElements){
            if(endpointOmElement!=null){
                String entryText = endpointOmElement.getText();
                if (endpointURL != null && entryText.contains(endpointURL) ){
                    endpointOmElement.detach();
                }
            }
        }
    }

    private static List<OMElement> getOmElements(OMElement serviceElement) throws RegistryException {
        List<OMElement> serviceEndpointEntryElements;
        try {
            serviceEndpointEntryElements = evaluateXPathToElements(SERVICE_ENDPOINT_ENTRY_EXPR, serviceElement);
        } catch (Exception e) {
            String msg = "Error in evaluating xpath expressions to extract endpoints";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        return serviceEndpointEntryElements;
    }

    public static void removeEndpointEntry(RequestContext requestContext, OMElement serviceElement ,String servicePath, Registry registry)
            throws RegistryException {
        Association[] associations = registry.getAssociations(servicePath, CommonConstants.DEPENDS);
        for (Association association: associations) {
            String targetPath = association.getDestinationPath();
            if (registry.resourceExists(targetPath)) {
                Resource targetResource = registry.get(targetPath);
                if (CommonConstants.ENDPOINT_MEDIA_TYPE.equals(targetResource.getMediaType())) {
                    registry.removeAssociation(servicePath, targetResource.getPath(),
                            CommonConstants.DEPENDS);
                    registry.removeAssociation(targetResource.getPath(), servicePath,
                            CommonConstants.USED_BY);
                }
            }
        }
        List<OMElement> serviceEndpointEntryElements = getOmElements(serviceElement);

        String serviceVersion = CommonUtil.getServiceVersion(serviceElement);
        endpointVersion = serviceVersion;
        for (OMElement endpointElement: serviceEndpointEntryElements) {
            Map<String, String> properties = new HashMap<String, String>();

            String entryText = endpointElement.getText();
            String entryKey = null;
            String entryVal;
            int colonIndex = entryText.indexOf(":");
            if (colonIndex < entryText.length()- 1) {
                entryKey = entryText.substring(0, colonIndex);
                entryText = entryText.substring(colonIndex + 1);
            }
            entryVal = entryText;

            if (!"".equals(entryKey)) {
                // here the key is the environment

                String endpointPath = RegistryUtils.getAbsolutePath(registry.getRegistryContext(),
                        org.wso2.carbon.registry.core.RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH +
                                endpointLocation) + deriveEndpointFromUrl(entryVal);

                String existingEnv = null;

                if (registry.resourceExists(endpointPath)) {
                    registry.get(endpointPath).removeProperty(CommonConstants.ENDPOINT_ENVIRONMENT_ATTR);
                }
                existingEnv = entryKey;
                properties.put(CommonConstants.ENDPOINT_ENVIRONMENT_ATTR, existingEnv);
            }

            // the entry value is the url
            saveEndpoint(requestContext, registry, entryVal, servicePath, properties, CommonUtil.getUnchrootedSystemRegistry(requestContext));
        }
    }

    public static void saveEndpointsFromWSDL(RequestContext context, String wsdlPath, Resource wsdlResource,
                                      Registry registry, Registry systemRegistry)
            throws RegistryException {
        // building the wsdl element.
        byte[] wsdlContentBytes = (byte[])wsdlResource.getContent();
        if (wsdlContentBytes == null) {
            return;
        }
        OMElement wsdlElement;
        try {
            wsdlElement = buildOMElement(RegistryUtils.decodeBytes(wsdlContentBytes));
        } catch (Exception e) {
            String msg = "Error in building the wsdl element for path: " + wsdlPath + ".";
            throw new RegistryException(msg, e);
        }

        // If the version field is not blank endpointVersion is modified accordingly
        if (StringUtils.isNotBlank(wsdlResource.getProperty("version"))) {
            endpointVersion = wsdlResource.getProperty("version");
        }

        // saving soap11 endpoints
        List<OMElement> soap11Elements;
        try {
            soap11Elements =  evaluateXPathToElements(SOAP11_ENDPOINT_EXPR, wsdlElement);
        } catch (Exception e) {
            String msg = "Error in evaluating xpath expressions to extract endpoints, wsdl path: " + wsdlPath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        for (OMElement soap11Element: soap11Elements) {
            String locationUrl = soap11Element.getAttributeValue(new QName(LOCATION_ATTR));
            Map<String, String> properties = new HashMap<String, String>();
            properties.put(CommonConstants.SOAP11_ENDPOINT_ATTRIBUTE, "true");
            properties.put(CommonConstants.SOURCE_PROPERTY, CommonConstants.SOURCE_AUTO);
            saveEndpoint(context,registry, locationUrl, wsdlPath, properties, systemRegistry);
        }

        // saving soap12 endpoints
        List<OMElement> soap12Elements;
        try {
            soap12Elements =  evaluateXPathToElements(SOAP12_ENDPOINT_EXPR, wsdlElement);
        } catch (Exception e) {
            String msg = "Error in evaluating xpath expressions to extract endpoints, wsdl path: " + wsdlPath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        for (OMElement soap12Element: soap12Elements) {
            String locationUrl = soap12Element.getAttributeValue(new QName(LOCATION_ATTR));
            Map<String, String> properties = new HashMap<String, String>();
            properties.put(CommonConstants.SOAP12_ENDPOINT_ATTRIBUTE, "true");
            properties.put(CommonConstants.SOURCE_PROPERTY, CommonConstants.SOURCE_AUTO);
            saveEndpoint(context, registry, locationUrl, wsdlPath, properties, systemRegistry);
        }

        // saving http endpoints
        List<OMElement> httpElements;
        try {
            httpElements =  evaluateXPathToElements(HTTP_ENDPOINT_EXPR, wsdlElement);
        } catch (Exception e) {
            String msg = "Error in evaluating xpath expressions to extract endpoints, wsdl path: " + wsdlPath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        for (OMElement httpElement: httpElements) {
            String locationUrl = httpElement.getAttributeValue(new QName(LOCATION_ATTR));
            Map<String, String> properties = new HashMap<String, String>();
            properties.put(CommonConstants.HTTP_ENDPOINT_ATTRIBUTE, "true");
            properties.put(CommonConstants.SOURCE_PROPERTY, CommonConstants.SOURCE_AUTO);
            saveEndpoint(context, registry, locationUrl, wsdlPath, properties, systemRegistry);
        }
    }
    public static void saveEndpointsFromWSDL(RequestContext context, String wsdlPath, Resource wsdlResource,
                                      Registry registry, Registry systemRegistry,String environment
            ,List<String> dependencies,String version) throws RegistryException {
        // building the wsdl element.
        byte[] wsdlContentBytes = (byte[])wsdlResource.getContent();
        if (wsdlContentBytes == null) {
            return;
        }
        OMElement wsdlElement;
        try {
            wsdlElement = buildOMElement(RegistryUtils.decodeBytes(wsdlContentBytes));
        } catch (Exception e) {
            String msg = "Error in building the wsdl element for path: " + wsdlPath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        // saving soap11 endpoints
        List<OMElement> soap11Elements;
        try {
            soap11Elements =  evaluateXPathToElements(SOAP11_ENDPOINT_EXPR, wsdlElement);
        } catch (Exception e) {
            String msg = "Error in evaluating xpath expressions to extract endpoints, wsdl path: " + wsdlPath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        for (OMElement soap11Element: soap11Elements) {
            String locationUrl = soap11Element.getAttributeValue(new QName(LOCATION_ATTR));
            Map<String, String> properties = new HashMap<String, String>();
            properties.put(CommonConstants.SOAP11_ENDPOINT_ATTRIBUTE, "true");
            properties.put(CommonConstants.SOURCE_PROPERTY, CommonConstants.SOURCE_AUTO);
            saveEndpoint(context,registry, locationUrl, wsdlPath, properties, systemRegistry,environment,dependencies,version);
        }

        // saving soap12 endpoints
        List<OMElement> soap12Elements;
        try {
            soap12Elements =  evaluateXPathToElements(SOAP12_ENDPOINT_EXPR, wsdlElement);
        } catch (Exception e) {
            String msg = "Error in evaluating xpath expressions to extract endpoints, wsdl path: " + wsdlPath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        for (OMElement soap12Element: soap12Elements) {
            String locationUrl = soap12Element.getAttributeValue(new QName(LOCATION_ATTR));
            Map<String, String> properties = new HashMap<String, String>();
            properties.put(CommonConstants.SOAP12_ENDPOINT_ATTRIBUTE, "true");
            properties.put(CommonConstants.SOURCE_PROPERTY, CommonConstants.SOURCE_AUTO);
            saveEndpoint(context, registry, locationUrl, wsdlPath, properties, systemRegistry,environment,dependencies,version);
        }

        // saving http endpoints
        List<OMElement> httpElements;
        try {
            httpElements =  evaluateXPathToElements(HTTP_ENDPOINT_EXPR, wsdlElement);
        } catch (Exception e) {
            String msg = "Error in evaluating xpath expressions to extract endpoints, wsdl path: " + wsdlPath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        for (OMElement httpElement: httpElements) {
            String locationUrl = httpElement.getAttributeValue(new QName(LOCATION_ATTR));
            Map<String, String> properties = new HashMap<String, String>();
            properties.put(CommonConstants.HTTP_ENDPOINT_ATTRIBUTE, "true");
            properties.put(CommonConstants.SOURCE_PROPERTY, CommonConstants.SOURCE_AUTO);
            saveEndpoint(context, registry, locationUrl, wsdlPath, properties, systemRegistry,environment,dependencies,version);
        }
    }

    public static void saveEndpointsFromServices(RequestContext context, String servicePath, OMElement serviceElement,
                                      Registry registry, Registry systemRegistry)
            throws RegistryException {

        // first iterate through soap11 endpoints
        // saving soap11 endpoints
        List<OMElement> serviceEndpointEntryElements = getOmElements(serviceElement);

        String serviceVersion = CommonUtil.getServiceVersion(serviceElement);
        endpointVersion = serviceVersion;

        // and add the associations and before adding them first remove all the endpoint dependencies
        removeEndpointDependencies(servicePath, registry);

        // iterate through the new endpoints..
        for (OMElement endpointElement: serviceEndpointEntryElements) {
            Map<String, String> properties = new HashMap<String, String>();

            String entryText = endpointElement.getText();
            String entryKey = null;
            String entryVal;
            int colonIndex = entryText.indexOf(":");
            if (colonIndex < entryText.length()- 1) {
                entryKey = entryText.substring(0, colonIndex);
                entryText = entryText.substring(colonIndex + 1);
            }
            entryVal = entryText;

            if (!"".equals(entryKey)) {
                // here the key is the environment

                String endpointPath = RegistryUtils.getAbsolutePath(registry.getRegistryContext(),
                        org.wso2.carbon.registry.core.RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH +
                                endpointLocation) + deriveEndpointFromUrl(entryVal);

                String existingEnv = null;

                if (registry.resourceExists(endpointPath)) {
                    registry.get(endpointPath).removeProperty(CommonConstants.ENDPOINT_ENVIRONMENT_ATTR);
                }
                existingEnv = entryKey;
                properties.put(CommonConstants.ENDPOINT_ENVIRONMENT_ATTR, existingEnv);
            }

            // the entry value is the url
            saveEndpoint(context, registry, entryVal, servicePath, properties, systemRegistry);
        }

        // and we are getting the endpoints of all the attached wsdls.

        addAssociations(servicePath, registry);
    }
    public static void saveEndpointsFromServices(RequestContext context,String servicePath, OMElement serviceElement,
                                      Registry registry, Registry systemRegistry,String environment)
            throws RegistryException {
        if (!CommonUtil.isAddingAssociationLockAvailable()) {
            return;
        }
        CommonUtil.acquireAddingAssociationLock();
        try {
            // first iterate through soap11 endpoints
            // saving soap11 endpoints
            List<OMElement> serviceEndpointEntryElements = getOmElements(serviceElement);

            // and add the associations and before adding them first remove all the endpoint dependencies
            removeEndpointDependencies(servicePath, registry);

            // iterate through the new endpoints..
            for (OMElement endpointElement: serviceEndpointEntryElements) {
                Map<String, String> properties = new HashMap<String, String>();

                String entryText = endpointElement.getText();
                String entryKey = null;
                String entryVal;
                int colonIndex = entryText.indexOf(":");
                if (colonIndex < entryText.length()- 1) {
                    entryKey = entryText.substring(0, colonIndex);
                    entryText = entryText.substring(colonIndex + 1);
                }
                entryVal = entryText;

                if (!"".equals(entryKey)) {
                    // here the key is the environment

                    String endpointPath = RegistryUtils.getAbsolutePath(registry.getRegistryContext(),
                            org.wso2.carbon.registry.core.RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH +
                                    environment) + deriveEndpointFromUrl(entryVal);

                    String existingEnv = null;

                    if (registry.resourceExists(endpointPath)) {
                        registry.get(endpointPath).removeProperty(CommonConstants.ENDPOINT_ENVIRONMENT_ATTR);
                    }
                    existingEnv = entryKey;
                    properties.put(CommonConstants.ENDPOINT_ENVIRONMENT_ATTR, existingEnv);
                }

                // the entry value is the url
                saveEndpoint(context,registry, entryVal, servicePath, properties, systemRegistry,environment);
            }
        } finally {
            CommonUtil.releaseAddingAssociationLock();
        }

        // and we are getting the endpoints of all the attached wsdls.

        addAssociations(servicePath, registry);
    }

    private static void addAssociations(String servicePath, Registry registry) throws RegistryException {
        Association[] associations = registry.getAssociations(servicePath, CommonConstants.DEPENDS);
        for (Association association: associations) {
            String targetPath = association.getDestinationPath();
            if (registry.resourceExists(targetPath)) {
                Resource targetResource = registry.get(targetPath);
                if (CommonConstants.WSDL_MEDIA_TYPE.equals(targetResource.getMediaType())) {
                    // for the wsdl, we are getting all the endpoints
                    Association[] wsdlAssociations = registry.getAssociations(targetPath,
                            CommonConstants.DEPENDS);
                    for (Association wsdlAssociation: wsdlAssociations) {
                        String wsdlTargetPath = wsdlAssociation.getDestinationPath();
                        if (registry.resourceExists(wsdlTargetPath)) {
                            Resource wsdlTargetResource = registry.get(wsdlTargetPath);
                            if (CommonConstants.ENDPOINT_MEDIA_TYPE.equals(
                                    wsdlTargetResource.getMediaType())) {
                                // so it is the wsdl associated to endpoints,
                                // so we associate these endpoints to the services as well.
                                registry.addAssociation(servicePath, wsdlTargetPath,
                                        CommonConstants.DEPENDS);
                                registry.addAssociation(wsdlTargetPath, servicePath,
                                        CommonConstants.USED_BY);
                            }
                        }
                    }
                }
            }
        }
    }

    private static void removeEndpointDependencies(String servicePath, Registry registry) throws RegistryException {
        // update lock check removed from for loop to prevent the database lock
            Association[] associations = registry.getAllAssociations(servicePath);
            for (Association association : associations) {
                String path = association.getDestinationPath();
                if (registry.resourceExists(path)) {
                    Resource endpointResource = registry.get(path);
                    if (CommonConstants.ENDPOINT_MEDIA_TYPE.equals(endpointResource.getMediaType())) {
                        registry.removeAssociation(servicePath, path, CommonConstants.DEPENDS);
                        registry.removeAssociation(path, servicePath, CommonConstants.USED_BY);
                    }
                }
            }
    }

    private static String[] wsdlPrefixes = {
            "wsdl", "http://schemas.xmlsoap.org/wsdl/",
            "wsdl2", "http://www.w3.org/ns/wsdl",
            "xsd", "http://www.w3.org/2001/XMLSchema",
            "soap", "http://schemas.xmlsoap.org/wsdl/soap/",
            "soap12", "http://schemas.xmlsoap.org/wsdl/soap12/",
            "http", "http://schemas.xmlsoap.org/wsdl/http/",
            "s", CommonConstants.SERVICE_ELEMENT_NAMESPACE,
    };

    private static List<OMElement> evaluateXPathToElements(String expression,
                                                           OMElement root) throws Exception {
        String[] nsPrefixes = wsdlPrefixes;
        AXIOMXPath xpathExpression = new AXIOMXPath(expression);

        for (int j = 0; j < nsPrefixes.length; j ++) {
            xpathExpression.addNamespace(nsPrefixes[j++], nsPrefixes[j]);
        }
        return (List<OMElement>)xpathExpression.selectNodes(root);
    }

    private static OMElement buildOMElement(String content) throws Exception {
        XMLStreamReader parser;
        try {
            parser = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(content));
        } catch (XMLStreamException e) {
            String msg = "Error in initializing the parser to build the OMElement.";
            throw new Exception(msg, e);
        }

        //create the builder
        StAXOMBuilder builder = new StAXOMBuilder(parser);
        //get the root element (in this case the envelope)

        return builder.getDocumentElement();
    }

    private static void saveEndpoint(RequestContext context, Registry registry, String url, String associatedPath,
                                     Map<String, String> properties, Registry systemRegistry, String environment)
                                     throws RegistryException {

        String pathExpression = getEndpointLocation(context, url, systemRegistry, environment);

        String urlToPath = deriveEndpointFromUrl(url);

        String endpointAbsoluteBasePath = RegistryUtils.getAbsolutePath(registry.getRegistryContext(),
                org.wso2.carbon.registry.core.RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH +
                environment);
        if (!systemRegistry.resourceExists(endpointAbsoluteBasePath)) {
            systemRegistry.put(endpointAbsoluteBasePath, systemRegistry.newCollection());
        }
        String relativePath = environment + urlToPath;
        String endpointAbsolutePath = pathExpression;
        saveEndpointValues(context, registry, url, associatedPath, properties, systemRegistry, relativePath,
                           endpointAbsolutePath);
    }

    private static void saveEndpoint(RequestContext context, Registry registry, String url, String associatedPath,
                                     Map<String, String> properties, Registry systemRegistry, String environment,
                                     List<String> dependencies, String version) throws RegistryException {
        String urlToPath = deriveEndpointFromUrl(url);

        String pathExpression = getEndpointLocation(context, url, systemRegistry, environment);

        String endpointAbsoluteBasePath = RegistryUtils.getAbsolutePath(registry.getRegistryContext(),
                environment);
        if (!systemRegistry.resourceExists(endpointAbsoluteBasePath)) {
            systemRegistry.put(endpointAbsoluteBasePath, systemRegistry.newCollection());
        }

        String prefix = urlToPath.substring(0,urlToPath.lastIndexOf(RegistryConstants.PATH_SEPARATOR) +1 );
        String name = urlToPath.replace(prefix,"");

        String regex = endpointAbsoluteBasePath + prefix + "[\\d].[\\d].[\\d]" + RegistryConstants.PATH_SEPARATOR + name;

        for (String dependency : dependencies) {
            if(dependency.matches(regex)){
                String newRelativePath =  RegistryUtils.getRelativePathToOriginal(dependency,
                        org.wso2.carbon.registry.core.RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH );
                saveEndpointValues(context,registry, url, associatedPath, properties, systemRegistry, newRelativePath, dependency);
                return;
            }
        }
        String endpointAbsolutePath = environment + prefix + version + RegistryConstants.PATH_SEPARATOR + name;
        String relativePath = environment.substring(0,RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH.length())
                + prefix + version + RegistryConstants.PATH_SEPARATOR + name;
        saveEndpointValues(context, registry, url, associatedPath, properties, systemRegistry, relativePath,
                           endpointAbsolutePath);
    }
    private static void saveEndpoint(RequestContext context, Registry registry, String url,
                                   String associatedPath, Map<String, String> properties,
                                   Registry systemRegistry) throws RegistryException {
        String urlToPath = deriveEndpointFromUrl(url);


        String pathExpression = getEndpointLocation(context, url, systemRegistry, endpointLocation);

        String endpointAbsoluteBasePath = RegistryUtils.getAbsolutePath(registry.getRegistryContext(),
                                          org.wso2.carbon.registry.core.RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH +
                                          endpointLocation);
        if (!systemRegistry.resourceExists(endpointAbsoluteBasePath)) {
            systemRegistry.put(endpointAbsoluteBasePath, systemRegistry.newCollection());
        }
        if(endpointLocation.endsWith(RegistryConstants.PATH_SEPARATOR)){
            if(urlToPath.startsWith(RegistryConstants.PATH_SEPARATOR)){
                urlToPath = urlToPath.replaceFirst(RegistryConstants.PATH_SEPARATOR,"");
            }
        }else{
            if(!urlToPath.startsWith(RegistryConstants.PATH_SEPARATOR)){
                urlToPath = RegistryConstants.PATH_SEPARATOR + urlToPath;
            }
        }
        String relativePath = endpointLocation + urlToPath;
        String  endpointAbsolutePath = pathExpression;

        saveEndpointValues(context, registry, url, associatedPath, properties, systemRegistry, relativePath,
                           endpointAbsolutePath);
    }

    /**
     * This method used to generate registry path of the endpoint. In the non-OSGi environment it will execute the else
     * condition
     * @param context Request Context
     * @param url Endpoint URL
     * @param systemRegistry Registry instance
     * @param environment Environment
     * @return Populated Registry Path
     * @throws RegistryException
     */
    private static String getEndpointLocation(RequestContext context, String url, Registry systemRegistry,
                                              String environment) throws RegistryException {
        if (Utils.getRxtService() != null) {
            String pathExpression = Utils.getRxtService().getStoragePath(CommonConstants.ENDPOINT_MEDIA_TYPE);
            pathExpression = CommonUtil
                    .replaceExpressionOfPath(pathExpression, "name", deriveEndpointNameWithNamespaceFromUrl(url));
            pathExpression = CommonUtil
                    .replaceExpressionOfPath(pathExpression, "version", endpointVersion);
            pathExpression =
                    CommonUtil.getPathFromPathExpression(pathExpression, context.getResource().getProperties(), null);
            String namespace = deriveEndpointNamespaceFromUrl(url).replace("//", "/");
            pathExpression = CommonUtil.replaceExpressionOfPath(pathExpression, "namespace", namespace);
            pathExpression = pathExpression.replace("//", "/");
            pathExpression =   RegistryUtils.getAbsolutePath(context.getRegistryContext(), pathExpression.replace("//", "/"));
            String endPointPath = pathExpression;
            /**
             * Fix for the REGISTRY-3052 : validation is to check the whether this invoked by ZIPWSDLMediaTypeHandler
             * Setting the registry and absolute paths to current session to avoid incorrect resource path entry in REG_LOG table
             */
            if (CurrentSession.getLocalPathMap() != null && !Boolean.valueOf(CurrentSession.getLocalPathMap().get(CommonConstants.ARCHIEVE_UPLOAD))) {
                endPointPath = CommonUtil.getRegistryPath(context.getRegistry().getRegistryContext(),pathExpression);
                if (log.isDebugEnabled()) {
                    log.debug("Saving current session local paths, key: " + endPointPath + " | value: " + pathExpression);
                }
                CurrentSession.getLocalPathMap().put(endPointPath, pathExpression);
            }
            return endPointPath;
        } else {
            String urlToPath = deriveEndpointFromUrl(url);
            String endpointAbsoluteBasePath = RegistryUtils.getAbsolutePath(context.getRegistryContext(),
                                              org.wso2.carbon.registry.core.RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH +
                                              environment);
            if (!systemRegistry.resourceExists(endpointAbsoluteBasePath)) {
                systemRegistry.put(endpointAbsoluteBasePath, systemRegistry.newCollection());
            }
            String endpointAbsolutePath = endpointAbsoluteBasePath + urlToPath;
            return endpointAbsolutePath;
        }
    }

    /**
     * Update endpoint content(XML structure) with properties coming though context, We assume those fields only in
     * overview section.
     *
     * @param context Request Context
     * @param content Current content of the endpoint
     * @return updated endpoint content
     */
    private static String updateEndpointContent(RequestContext context, String content) {
        try {
            OMElement serviceElement = buildOMElement(content);
            String pathExpression = Utils.getRxtService().getStoragePath(CommonConstants.ENDPOINT_MEDIA_TYPE);
            CommonUtil.getPathFromPathExpression(pathExpression, context.getResource().getProperties(), serviceElement);
            return serviceElement.toString();
        } catch (Exception e) {
            // If exception occurred while generating OMElement, then will return the original content
        }
        return content;
    }

    private static void saveEndpointValues(RequestContext context,Registry registry, String url, String associatedPath
            , Map<String, String> properties, Registry systemRegistry, String relativePath
            , String endpointAbsolutePath) throws RegistryException {
        Resource resource;
        String endpointId = null;
        if (registry.resourceExists(endpointAbsolutePath)) {
            resource = registry.get(endpointAbsolutePath);
            endpointId = resource.getUUID();
            String existingContent;
            String newContent = updateEndpointContent(context, getEndpointContentWithOverview(url, endpointAbsolutePath,
                                                      ((ResourceImpl) resource).getName(),endpointVersion));
            if (resource.getContent() != null) {
                existingContent = new String((byte[]) (resource.getContent()));
                if (!existingContent.equals(newContent)) {
                    resource.setContent(RegistryUtils.encodeString(newContent));
                }
            } else {
                resource.setContent(RegistryUtils.encodeString(newContent));
            }
        } else {
            resource = registry.newResource();
            resource.setContent(RegistryUtils.encodeString(updateEndpointContent(context,
                                                        getEndpointContentWithOverview(url,endpointAbsolutePath,
                                                        deriveEndpointNameWithNamespaceFromUrl(url),endpointVersion))));
        }
        boolean endpointIdCreated = false;
        if (endpointId == null) {
            endpointIdCreated = true;
            endpointId = UUID.randomUUID().toString();
            resource.setUUID(endpointId);
        }

//        CommonUtil.addGovernanceArtifactEntryWithRelativeValues(
//                systemRegistry, endpointId, relativePath);

        boolean propertiesChanged = false;
        if (properties != null) {
            for (Map.Entry<String, String> e : properties.entrySet()) {
                propertiesChanged = true;
                resource.setProperty(e.getKey(), e.getValue());
            }
        }

        if (endpointIdCreated || propertiesChanged) {
            // this will be definitely false for a brand new resource
            resource.setMediaType(endpointMediaType);
            registry.put(endpointAbsolutePath, resource);
            // we need to create a version here.
        }
        String defaultLifeCycle = CommonUtil.getDefaultLifecycle(registry, "endpoint");
        CommonUtil.applyDefaultLifeCycle(registry, resource, endpointAbsolutePath, defaultLifeCycle);
        registry.addAssociation(associatedPath, endpointAbsolutePath, CommonConstants.DEPENDS);
        registry.addAssociation(endpointAbsolutePath, associatedPath, CommonConstants.USED_BY);
    }

    public static void addEndpointToService(Registry registry,
                                            String servicePath,
                                            String endpointUrl,
                                            String endpointEnv) throws RegistryException {
        Resource serviceResource = registry.get(servicePath);
        byte[] serviceBytes = (byte[])serviceResource.getContent();
        String serviceContent = RegistryUtils.decodeBytes(serviceBytes);

        OMElement serviceElement;
        try {
            serviceElement = buildOMElement(serviceContent);
        } catch (Exception e) {
            String msg = "Failed building the service element. " + servicePath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        OMElement serviceEndpointElement;
        OMNamespace namespace = OMAbstractFactory.getOMFactory().createOMNamespace(
                CommonConstants.SERVICE_ELEMENT_NAMESPACE, null);
        try {
            List<OMElement> endpointElements = evaluateXPathToElements(
                    SERVICE_ENDPOINT_EXPR, serviceElement);
            if (endpointElements.size() == 0) {
                // we need to create the element.
                serviceEndpointElement =
                        OMAbstractFactory.getOMFactory().createOMElement(
                                SERVICE_ENDPOINTS_ELEMENT, namespace);
                serviceElement.addChild(serviceEndpointElement);
            } else {
                serviceEndpointElement = endpointElements.get(0);
            }
        } catch (Exception e) {
            String msg = "Error in getting the endpoint element of the service. " +
                    "service path: " + servicePath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        Iterator it = serviceEndpointElement.getChildElements();
        List<String> currentEndpoints = new ArrayList<String>();
        while(it.hasNext()){
            currentEndpoints.add(((OMElement) it.next()).getText());
        }
        if(!currentEndpoints.contains(endpointEnv + ":" + endpointUrl)){
            OMElement entryElement =
                    OMAbstractFactory.getOMFactory().createOMElement(
                            SERVICE_ENDPOINTS_ENTRY_ELEMENT, namespace);
            entryElement.setText(endpointEnv + ":" + endpointUrl);
            serviceEndpointElement.addChild(entryElement);

            // now we are saving it to the registry.
            String serviceElementStr = serviceElement.toString();
            serviceResource.setContent(RegistryUtils.encodeString(serviceElementStr));
            registry.put(servicePath, serviceResource);
        }
    }


    public static OMElement addEndpointToService(OMElement serviceElement,
                                                 String endpointUrl,
                                                 String endpointEnv) throws RegistryException {
        OMElement serviceEndpointElement;
        OMNamespace namespace = OMAbstractFactory.getOMFactory().createOMNamespace(
                CommonConstants.SERVICE_ELEMENT_NAMESPACE, null);
        try {
            List<OMElement> endpointElements = evaluateXPathToElements(SERVICE_ENDPOINT_EXPR, serviceElement);
            if (endpointElements.size() == 0) {
                // we need to create the element.
                serviceEndpointElement = OMAbstractFactory.getOMFactory().createOMElement(
                        SERVICE_ENDPOINTS_ELEMENT, namespace);
                serviceElement.addChild(serviceEndpointElement);
            } else {
                serviceEndpointElement = endpointElements.get(0);
            }
        } catch (Exception e) {
            String msg = "Error in getting the endpoint element of the service.";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        Iterator it = serviceEndpointElement.getChildElements();
        List<String> currentEndpoints = new ArrayList<String>();
        while (it.hasNext()) {
            currentEndpoints.add(((OMElement) it.next()).getText());
        }
        if (!currentEndpoints.contains(endpointEnv + ":" + endpointUrl)) {
            OMElement entryElement = OMAbstractFactory.getOMFactory().createOMElement(
                    SERVICE_ENDPOINTS_ENTRY_ELEMENT, namespace);
            entryElement.setText(endpointEnv + ":" + endpointUrl);
            serviceEndpointElement.addChild(entryElement);

            // now we are saving it to the registry.
            return serviceElement;
        }
        return serviceElement;
    }


    public static void removeEndpointFromService(Registry registry,
                                            String servicePath,
                                            String endpointUrl,
                                            String endpointEnv) throws RegistryException {
        Resource serviceResource = registry.get(servicePath);
        byte[] serviceBytes = (byte[])serviceResource.getContent();
        String serviceContent = RegistryUtils.decodeBytes(serviceBytes);

        OMElement serviceElement;
        try {
            serviceElement = buildOMElement(serviceContent);
        } catch (Exception e) {
            String msg = "Failed building the service element. " + servicePath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        OMElement serviceEndpointElement;
        OMNamespace namespace = OMAbstractFactory.getOMFactory().createOMNamespace(
                CommonConstants.SERVICE_ELEMENT_NAMESPACE, null);
        try {
            List<OMElement> endpointElements = evaluateXPathToElements(
                    SERVICE_ENDPOINT_EXPR, serviceElement);
            if (endpointElements.size() == 0) {
                // we need to create the element.
                serviceEndpointElement =
                        OMAbstractFactory.getOMFactory().createOMElement(
                                SERVICE_ENDPOINTS_ELEMENT, namespace);
                serviceElement.addChild(serviceEndpointElement);
            } else {
                serviceEndpointElement = endpointElements.get(0);
            }
        } catch (Exception e) {
            String msg = "Error in getting the endpoint element of the service. " +
                    "service path: " + servicePath + ".";
            log.error(msg, e);
            throw new RegistryException(msg, e);
        }
        Iterator it = serviceEndpointElement.getChildElements();
        while(it.hasNext()){
            OMElement next = (OMElement) it.next();
            if (next.getText().equals(endpointEnv + ":" + endpointUrl)) {
                next.detach();
                // now we are saving it to the registry.
                String serviceElementStr = serviceElement.toString();
                serviceResource.setContent(RegistryUtils.encodeString(serviceElementStr));
                registry.put(servicePath, serviceResource);
                break;
            }
        }
    }

    /**
     * Returns an endpoint path for the url without the starting '/'
     * @param url the endpoint url
     * @return the path
     */
    public static String deriveEndpointFromUrl(String url) {
        if (StringUtils.isBlank(url)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint name from url.");
        }
        String[] temp = url.split("[?]")[0].split("/");
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<temp.length-1; i++){
            sb.append(temp[i]).append("/");
        }
        String urlToPath = CommonUtil.derivePathFragmentFromNamespace(sb.toString());
        // excluding extra slashes.
        if (urlToPath.length() > 1) {
            urlToPath = urlToPath.substring(1, urlToPath.length() - 1);
        }
        urlToPath += "/" + deriveEndpointNameFromUrl(url);
        return urlToPath;
    }

    /**
     * Returns an endpoint path for the url without the starting '/'
     * @param url the endpoint url
     * @return the path
     */
    public static String deriveEndpointNamespaceFromUrl(String url) {
        if (StringUtils.isBlank(url)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint name from url.");
        }
        String[] temp = url.split("[?]")[0].split("/");
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<temp.length-1; i++){
            sb.append(temp[i]).append("/");
        }
        String urlToPath = CommonUtil.derivePathFragmentFromNamespace(sb.toString());
        // excluding extra slashes.
        if (urlToPath.length() > 1) {
            urlToPath = urlToPath.substring(1, urlToPath.length() - 1);
        }
       return urlToPath;
    }

    /**
     * Returns an endpoint name with ENDPOINT_RESOURCE_PREFIX
     *
     * @param url the endpoint url
     * @return (ENDPOINT_RESOURCE_PREFIX + name) populated resource name
     */
    public static String deriveEndpointNameFromUrl(String url) {
        if (StringUtils.isBlank(url)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint name from url.");
        }
        String tempURL = url;
        if (tempURL.startsWith("jms:/")) {
            tempURL = tempURL.split("[?]")[0];
        }
        String name = tempURL.split("/")[tempURL.split("/").length - 1].replace(".", "-").
                replace("=", "-").replace("@", "-").replace("#", "-").replace("~", "-");

        return ENDPOINT_RESOURCE_PREFIX + name;
    }

    /**
     * Returns an endpoint name with namespace and ENDPOINT_RESOURCE_PREFIX
     *
     * @param url the endpoint url
     * @return (ENDPOINT_RESOURCE_PREFIX + namespace + name) populated resource name
     */
    public static String deriveEndpointNameWithNamespaceFromUrl(String url) {
        if (StringUtils.isBlank(url)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint name from url.");
        }
        String tempURL = url;
        if (tempURL.startsWith("jms:/")) {
            tempURL = tempURL.split("[?]")[0];
        }
        String name = tempURL.split("/")[tempURL.split("/").length - 1].replace(".", "-").
                replace("=", "-").replace("@", "-").replace("#", "-").replace("~", "-");
        String namespace =  deriveEndpointNamespaceFromUrl(url).replace("//", "/");
        namespace = namespace.replace("/", ".");
        namespace += "-";
        if (isIncludeNamespaceInName()){
            return ENDPOINT_RESOURCE_PREFIX + namespace +name;
        } else {
            return ENDPOINT_RESOURCE_PREFIX + name;
        }
    }

    /**
     * Create the endpoint content
     * This method is replaced by getEndpointContentWithOverview() below.
     *
     * @param endpoint endpoint URI
     * @param path endpoint location in the registry
     * @return
     * @throws RegistryException
     */
    @Deprecated
    public static String getEndpointContent(String endpoint, String path) throws RegistryException {
        if (StringUtils.isBlank(endpoint) || StringUtils.isBlank(path)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint name from url.");
        }
        path = setFullPath(path);
        OMFactory factory = OMAbstractFactory.getOMFactory();
        OMElement endpointElement = factory
                .createOMElement(new QName(ENDPOINT_ELEMENT_NAMESPACE, SYNAPSE_ENDPOINT, null));
        endpointElement.addAttribute(SYNAPSE_ENDPOINT_NAME_ATTRIBUTE, path, null);
        OMElement address = factory.createOMElement(new QName(SYNAPSE_ENDPOINT_ADDRESS));
        address.addAttribute(SYNAPSE_ENDPOINT_ADDRESS_URI_ATTRIBUTE, endpoint, null);
        endpointElement.addChild(address);
        return endpointElement.toString();
    }

    /**
     * Create the endpoint content with name and version
     *
     * @param endpoint endpoint URI
     * @param path endpoint location in the registry
     * @param name resource name
     * @param version resource version
     * @return OMElement.toString()
     * @throws RegistryException
     */
    public static String getEndpointContentWithOverview(String endpoint, String path, String name, String version)
            throws RegistryException {
        if (isArgumentsNull(endpoint, path, name, version)) {
            throw new IllegalArgumentException("Invalid arguments supplied for content creation.");
        }
        path = setFullPath(path);
        OMFactory factory = OMAbstractFactory.getOMFactory();
        OMElement endpointElement = factory.createOMElement(new QName(SYNAPSE_ENDPOINT));
        // Workaround for manually set xml namespace value.
        endpointElement.addAttribute(ENDPOINT_NAMESPACE_ATTRIBUTE, ENDPOINT_ELEMENT_NAMESPACE, null);
        //endpointElement.addAttribute(SYNAPSE_ENDPOINT_NAME_ATTRIBUTE, path, null);
        OMElement endpointElementOverview = factory.createOMElement(new QName(SYNAPSE_ENDPOINT_OVERVIEW));
        OMElement overviewName = factory.createOMElement(new QName(SYNAPSE_ENDPOINT_NAME));
        overviewName.setText(name);
        OMElement overviewVersion = factory.createOMElement(new QName(SYNAPSE_ENDPOINT_VERSION));
        overviewVersion.setText(version);
        OMElement overviewAddress = factory.createOMElement(new QName(SYNAPSE_ENDPOINT_ADDRESS));
        overviewAddress.setText(endpoint);
        endpointElementOverview.addChild(overviewName);
        endpointElementOverview.addChild(overviewVersion);
        endpointElementOverview.addChild(overviewAddress);
        endpointElement.addChild(endpointElementOverview);
        return endpointElement.toString();
    }

    /**
     * Create the endpoint content with name and version
     *
     * @param path endpoint location in the registry
     * @return path simplified concatenated path
     */
    private static String setFullPath(String path) {
        if (path.startsWith(RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH)) {
            path = "gov/" + path.substring((RegistryConstants.
                    GOVERNANCE_REGISTRY_BASE_PATH + ENDPOINT_DEFAULT_LOCATION).length());
        } else {
            path = "gov/" + path;
        }
        return path;
    }

    /**
     * Extract endpoint URL from content
     *
     * @param endpointContent endpoint content
     * @return addressElement.getText() String endpoint content
     * @throws RegistryException
     */
    public static String deriveEndpointFromContent(String endpointContent) throws RegistryException {
        if (StringUtils.isBlank(endpointContent)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint from content.");
        }
        try {
            OMElement endpointElement = AXIOMUtil.stringToOM(endpointContent);
            OMElement overviewElement = endpointElement
                    .getFirstChildWithName(new QName(ENDPOINT_ELEMENT_NAMESPACE, SYNAPSE_ENDPOINT_OVERVIEW));
            OMElement addressElement = overviewElement
                    .getFirstChildWithName(new QName(ENDPOINT_ELEMENT_NAMESPACE, SYNAPSE_ENDPOINT_ADDRESS));
            return addressElement.getText();
        } catch (XMLStreamException e) {
            throw new RegistryException("Invalid endpoint content", e);
        }
    }

    /**
     * Extract endpoint version from content
     *
     * @param endpointContent endpoint content
     * @return addressElement.getText() String endpoint version
     * @throws RegistryException
     */
    public static String deriveVersionFromContent(String endpointContent) throws RegistryException {
        if (StringUtils.isBlank(endpointContent)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint version from content.");
        }
        try {
            OMElement endpointElement = AXIOMUtil.stringToOM(endpointContent);
            OMElement overviewElement = endpointElement
                    .getFirstChildWithName(new QName(ENDPOINT_ELEMENT_NAMESPACE, SYNAPSE_ENDPOINT_OVERVIEW));
            OMElement addressElement = overviewElement
                    .getFirstChildWithName(new QName(ENDPOINT_ELEMENT_NAMESPACE, SYNAPSE_ENDPOINT_VERSION));
            return addressElement.getText();
        } catch (XMLStreamException e) {
            throw new RegistryException("Invalid endpoint content", e);
        }
    }

    /**
     * Extract endpoint name from content
     *
     * @param endpointContent endpoint content
     * @return addressElement.getText() String endpoint name
     * @throws RegistryException
     */
    public static String deriveNameFromContent(String endpointContent) throws RegistryException {
        if (StringUtils.isBlank(endpointContent)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint name from content.");
        }
        try {
            OMElement endpointElement = AXIOMUtil.stringToOM(endpointContent);
            OMElement overviewElement = endpointElement
                    .getFirstChildWithName(new QName(ENDPOINT_ELEMENT_NAMESPACE, SYNAPSE_ENDPOINT_OVERVIEW));
            OMElement addressElement = overviewElement
                    .getFirstChildWithName(new QName(ENDPOINT_ELEMENT_NAMESPACE, SYNAPSE_ENDPOINT_NAME));
            return addressElement.getText();
        } catch (XMLStreamException e) {
            throw new RegistryException("Invalid endpoint content", e);
        }
    }

    /**
     * Check whether all the parameters are null or not
     * "null" is considered as a valid string.
     *
     * @param value1,value2,value3,value4 argument String values
     * @return boolean value of isBlank()
     */
    private static boolean isArgumentsNull(String value1, String value2, String value3, String value4) {
        return StringUtils.isBlank(value1) || StringUtils.isBlank(value2) || StringUtils.isBlank(value3) ||
                StringUtils.isBlank(value4);
    }

    public static OMElement deriveOMElementContent(String endpointContent) throws RegistryException {
        if (StringUtils.isBlank(endpointContent)) {
            throw new IllegalArgumentException("Invalid arguments supplied for derive endpoint name from content.");
        }
        try {
            OMElement endpointElement = AXIOMUtil.stringToOM(endpointContent);

            return endpointElement;
        } catch (XMLStreamException e) {
            throw new RegistryException("Invalid endpoint content", e);
        }
    }
}
